#ifndef __CROSSFIRE_COLLISIONDETECTION
#define __CROSSFIRE_COLLISIONDETECTION

enum ECF_TraceType
{
  Ray,
  Box,
  Shpeare
};

struct SCF_CollisionInfo
{
  bool IsCollision;
  bool TryStep;
  bool IsGround;

  float TraceRatio;
  float TraceRadius;

  D3DXVECTOR3 Normal;
  D3DXVECTOR3 Position;
  D3DXVECTOR3 TraceMaxs;
  D3DXVECTOR3 TraceMins;
  D3DXVECTOR3 Extents;

  ECF_TraceType TraceType;
};

class CCF_CollisionDetection
{
private:
	CCF_Log* m_pLog;
	CCF_Bsp* m_pBspMap;

	BSP_LEAF *m_pLeaves;
	BSP_BRUSH *m_pBrushes;
	BSP_NODE *m_pNodes;
	BSP_PLANE *m_pPlanes;
	BSP_BRUSHSIDES *m_pBrushSides;
	BSP_TEXTURE *m_pTextures;
	BSP_LEAFBRUSHES *m_pLeafBrushes;
public:
	SCF_CollisionInfo m_collInfo;

	CCF_CollisionDetection();
	~CCF_CollisionDetection();

    bool Initialize(CCF_Bsp* Bsp_Map);

	void TraceRay(D3DXVECTOR3 vStart, D3DXVECTOR3 vEnd);
	void TraceSphere(D3DXVECTOR3 vStart, D3DXVECTOR3 vEnd, float radius);
	void TraceBox(D3DXVECTOR3 vStart, D3DXVECTOR3 vEnd, D3DXVECTOR3 vMin, D3DXVECTOR3 vMax);
private:
	void TryToStep(D3DXVECTOR3 vStart, D3DXVECTOR3 vEnd);
	void Trace(D3DXVECTOR3 vStart, D3DXVECTOR3 vEnd);

	void CheckNode(int nodeIndex, float startRatio, float endRatio, 
		D3DXVECTOR3 vStart, D3DXVECTOR3 vEnd);
	void CheckBrush(BSP_BRUSH *pBrush, D3DXVECTOR3 vStart, D3DXVECTOR3 vEnd);
};

#endif